在昨天我們教大家進行後端API的開發,接下來就要教大家前端的串接,這部分的內容可能比較深,大家可以慢慢熟練每個環節,再嘗試一口氣串接起來。
在這個部分,前端除了要取得API資料之外,我們還要計算我們要查詢的是哪一週,這個也需要有一點JS的知識,也可以當作是個簡單的小挑戰。
那就讓我們開始吧!
照著前面的教學邏輯,我們先從資料庫開發,然後是服務,最後是前端頁面。我們前端也可以按照這個邏輯,因為前端不需要開發資料庫,只要從服務開始,所以我們來到Service.js中,來開發這個取得週數的功能
整個邏輯非常簡單,我們只要輸入year, week,然後就會回傳所有的資料
export const getAccountsByWeek = (year,week)=>axios.get(BASE_REST_API_URL+'/weekly/'+year+"/"+week)
完成這個服務之後,我們就要創建新的頁面,我們來到Component資料夾中,新建一個WeeklyAccountComponent.jsx,然後開始撰寫我們的前端頁面。
我們最初在教React架構的時候,有提到React的設計邏輯,現在也要照著這個邏輯進行開發。
首先,這個頁面需要得到的資料就是年份、週數,以及取得到的帳目。
在讀取網頁的時候,我們就要先取得年份與週數,然後輸入到服務中,獲得相關的Account資料,最後呈現在頁面上。
所以在useEffect中我們要提供年份週數,並且取得所有帳目,我們可以把這兩個拆成兩個function,就是getWeeklyAccount跟getWeekNumber。
在網頁中,我們用table的形式來呈現我們的資料,關鍵字就是id,然後根據id順序來呈現名稱、類別、金額與收支
import React, { useEffect, useState } from 'react';
import { getAccountsByWeek } from '../Service/AccountService';
const WeeklyAccountComponent = () => {
const [year, setYear] = useState('');
const [week, setWeek] = useState('');
const [accounts, setAccounts] = useState([]);
useEffect(() => {
// 取得當前年份和週數
const currentDate = new Date()
const currentYear = currentDate.getFullYear()
const currentWeek = getWeekNumber(currentDate)
setYear(currentYear)
setWeek(currentWeek)
console.log('year:'+year+' week:'+week)
getWeeklyAccount(currentYear,currentWeek)
},[year,week]);
function getWeeklyAccount(year,week){
getAccountsByWeek(year,week).then((response)=>{
console.log(response.data)
setAccounts(response.data)
}).catch(error=>{
console.error(error)
})
}
// 取得張前週數
const getWeekNumber = (date) => {
const firstDayOfYear = new Date(date.getFullYear(), 0, 1);
const pastDaysOfYear = (date - firstDayOfYear) / 86400000;
return Math.ceil((pastDaysOfYear + firstDayOfYear.getDay() + 1) / 7);
};
return (
<div className='container'>
<h2 className='text-center'>Weekly Account List for Year {year}, Week {week}</h2>
<div className='mt-4'>
{accounts.length > 0 ? (
<table className='table table-bordered table-striped'>
<thead>
<tr>
<th>Account Name</th>
<th>Account Category</th>
<th>Account Amount</th>
<th>Account Expense</th>
</tr>
</thead>
<tbody>
{accounts.map((account) => (
<tr key={account.id}>
<td>{account.name}</td>
<td>{account.category}</td>
<td>{account.amount}</td>
<td>{account.expensed ? '支出' : '收入'}</td>
</tr>
))}
</tbody>
</table>
) : (
<div className='text-center'>
<p>No accounts found for this week.</p>
</div>
)}
</div>
</div>
)
}
export default WeeklyAccountComponent
寫到這裡,就算是寫完這個頁面
header修改
接下來我們就要在Header中新增這個連結。
主要的html程式碼如下
</li>
<li className='nav-item'>
<NavLink to="/week-account" className="nav-link">Sort Account</NavLink>
</li>
完整的Html如下
/* eslint-disable no-unused-vars */
import React, { useState } from 'react'
import { NavLink } from 'react-router-dom'
const HeaderComponent = () => {
return (
<div>
<header>
<nav className='navbar navbar-expand-md navbar-dark bg-dark'>
<div>
<a href='http://localhost:5173/' className='navbar-brand'>
Account Manager Application</a>
</div>
<div className='collapse navbar-collapse'>
<ul className='navbar-nav'>
<li className='nav-item'>
<NavLink to="/lsit-account" className="nav-link">Account List</NavLink>
</li>
<li className='nav-item'>
<NavLink to="/sort-account" className="nav-link">Sort Account</NavLink>
</li>
<li className='nav-item'>
<NavLink to="/week-account" className="nav-link">Sort Account</NavLink>
</li>
</ul>
</div>
</nav>
</header>
</div>
)
}
export default HeaderComponent
完成之後,我們要設定他的網址,我們可以到app.jsx中,新增這個頁面的轉址方式。
/* eslint-disable no-unused-vars */
import React, { useState } from 'react'
import { NavLink } from 'react-router-dom'
const HeaderComponent = () => {
return (
<div>
<header>
<nav className='navbar navbar-expand-md navbar-dark bg-dark'>
<div>
<a href='http://localhost:5173/' className='navbar-brand'>
Account Manager Application</a>
</div>
<div className='collapse navbar-collapse'>
<ul className='navbar-nav'>
<li className='nav-item'>
<NavLink to="/lsit-account" className="nav-link">Account List</NavLink>
</li>
<li className='nav-item'>
<NavLink to="/sort-account" className="nav-link">Sort Account</NavLink>
</li>
<li className='nav-item'>
<NavLink to="/week-account" className="nav-link">Week Account</NavLink>
</li>
</ul>
</div>
</nav>
</header>
</div>
)
}
export default HeaderComponent
設定好之後,就會出現以下結果
到這裡,我們就完成了更進階一點的從後端到前端的開發功能了!